package com.example.security.config;

import com.example.security.domain.ShiroUserDetail;
import com.example.security.exception.PrefixNotFoundException;
import com.example.security.properties.CompanyProperties;
import com.example.security.provider.base.UserProvider;
import com.example.security.utils.ShiroUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;

@Slf4j
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private CompanyProperties companyProperties;

    private final Map<String, UserProvider> userProviderMap;

    @Autowired
    public UserRealm(Map<String, UserProvider> userProviderMap) {
        this.userProviderMap = userProviderMap;
    }

    /**
     * 执行授权逻辑
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.warn("这是授权界面:[{}]", ShiroUtils.getUser().toString());
        log.info("执行授权逻辑");
        // 设置授权
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        ShiroUserDetail mpUserInfo = (ShiroUserDetail) principalCollection.getPrimaryPrincipal();
        List<String> perms = mpUserInfo.getPerms();
        if (perms != null && perms.size() > 0) {
            for (String perm : perms) {
                info.addStringPermission(perm);
            }
            log.warn("用户拥有的权限是:{}", info.getStringPermissions());
        } else {
            info.addStringPermission(null);
            log.warn("用户没有任何拥有的权限");
        }
        return info;
    }

    /**
     * 执行认证逻辑
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException e.g. username form:company:linenxi ;password 123456 代表表单登入
     *                                 username mobile:company:13587872968; password 10086 代表验证码登入
     *                                 username social:company:azkjckjzc password openId:company:wx 代表社交登入中的威信登入
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        log.warn("shiro登入框架执行 > ============= > ============= > ");
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        String[] eages = username.split(":" + companyProperties.getLoginSplit() + ":");
        if (eages.length == 1) {
            throw new PrefixNotFoundException("未写登入前缀错误!!!");
        }
        log.warn("登入方式为:[ {} ] ,主体为:[ {} ]", eages[0], eages[1]);
        String prefix = eages[0];
        UserProvider userProvider = userProviderMap.get(prefix.concat("UserProviderImpl"));
        if (userProvider == null) {
            throw new PrefixNotFoundException("登入前缀错误!!!");
        }
        return userProvider.doGetAuthenticationInfo(token);
    }
}
